Skip to content

feat(core): custom-method support (3-arg setRequestHandler + request schema overload)#1974

Merged
felixweinberger merged 10 commits into
mainfrom
fweinberger/custom-methods-minimal
Apr 29, 2026
Merged

feat(core): custom-method support (3-arg setRequestHandler + request schema overload)#1974
felixweinberger merged 10 commits into
mainfrom
fweinberger/custom-methods-minimal

Conversation

@felixweinberger

@felixweinberger felixweinberger commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Stacks on #1976 (_wrapHandler hook refactor). Review that first.

Custom (non-spec) method support: typed registration and sending. Replaces the #1891 / #1916 / #1917 chain with a single overload-based design. Protocol stays private (dispatcher RFC handles framework subclassing).

  • setRequestHandler / setNotificationHandler gain a 3-arg form: (method, { params, result? }, handler). params is any Standard Schema; the handler receives the parsed params object. _meta is stripped before validation (available as ctx.mcpReq._meta). Supplying result types the handler's return value.
  • request() and ctx.mcpReq.send gain a (req, resultSchema) overload for typed custom-method results.

Spec-method calls are unchanged (2-arg setRequestHandler, 1-arg request()). 2 overloads each on setRequestHandler/setNotificationHandler/request.

Motivation and Context

v2-main's setRequestHandler/request() only accept the closed RequestMethod/NotificationMethod unions, so vendor-prefixed methods (which the spec permits) cannot be registered or sent. The #1891/#1916/#1917 stack solved this with both v1-compat ZodSchema overloads and a ProtocolSpec<SpecT> typed-vocabulary mechanism; this PR is the minimal cut: one new overload per method. See discussion on #1891.

How Has This Been Tested?

packages/core/test/shared/customMethods.test.ts (9 tests): 3-arg registration, params validation, _meta strip, typed return via result, request() schema overload, mcpReq.send schema overload. typecheck/lint/build/docs/test:all clean locally.

Breaking Changes

None to v2-main. v1's setRequestHandler(ZodSchema, h) form is not restored here; it is mechanically codemod-able to the 3-arg form (#1950).

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

Alternative to #1891 / #1916 / #1917 (which stay open for comparison). Internally widens _requestWithSchema and the TaskManager send-chain from Zod-only AnySchema to StandardSchemaV1; Zod schemas implement StandardSchemaV1 so existing internal callers are unchanged.

Protocol is intentionally not exported in this PR. A separate dispatcher RFC (gist) covers the framework-subclassing use case; until that lands, Protocol stays internal-only.

Includes a _wrapHandler protected hook so subclass per-method validation (tools/call in Server, elicitation/create/sampling/createMessage in Client) does not require redeclaring setRequestHandler's overload set. The hook runs for both registration paths; validation behavior is unchanged.

@felixweinberger felixweinberger added the v2-bc v2 backwards-compatibility series label Apr 28, 2026
@pkg-pr-new

pkg-pr-new Bot commented Apr 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@1974

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@1974

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@1974

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@1974

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@1974

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@1974

commit: 5568303

@changeset-bot

changeset-bot Bot commented Apr 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5568303

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 7 packages
Name Type
@modelcontextprotocol/core Minor
@modelcontextprotocol/client Minor
@modelcontextprotocol/server Minor
@modelcontextprotocol/node Major
@modelcontextprotocol/express Major
@modelcontextprotocol/fastify Major
@modelcontextprotocol/hono Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@felixweinberger felixweinberger changed the title feat(core): custom-method support (3-arg setRequestHandler + request schema overload + export Protocol) feat(core): custom-method support (3-arg setRequestHandler + request schema overload) Apr 28, 2026
@felixweinberger felixweinberger marked this pull request as ready for review April 28, 2026 17:00
@felixweinberger felixweinberger requested a review from a team as a code owner April 28, 2026 17:00
Comment thread docs/migration-SKILL.md
Comment thread packages/client/src/client/client.ts
Comment thread packages/core/src/types/schemas.ts
Comment thread packages/core/src/shared/protocol.examples.ts Outdated
Comment thread packages/core/src/shared/protocol.ts
Comment thread docs/migration.md Outdated
Comment thread packages/core/src/shared/protocol.ts
@felixweinberger felixweinberger force-pushed the fweinberger/1974a-wraphandler branch from 8f12176 to e69c6a7 Compare April 28, 2026 20:42
@felixweinberger felixweinberger force-pushed the fweinberger/custom-methods-minimal branch from 37df126 to c3382eb Compare April 28, 2026 20:49
Comment thread packages/core/src/shared/protocol.ts Outdated
Comment thread examples/client/src/customMethodExample.ts Outdated
Comment thread packages/core/src/exports/public/index.ts

@KKonstantinov KKonstantinov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, some potential nits, not blocking.

Comment thread packages/client/src/client/client.ts Outdated
Comment thread packages/client/src/client/client.ts Outdated
KKonstantinov
KKonstantinov previously approved these changes Apr 29, 2026
Comment thread packages/core/src/shared/protocol.ts
Comment thread .changeset/custom-methods-minimal.md
Comment thread packages/core/src/shared/protocol.ts Outdated
Base automatically changed from fweinberger/1974a-wraphandler to main April 29, 2026 12:34
@felixweinberger felixweinberger dismissed KKonstantinov’s stale review April 29, 2026 12:34

The base branch was changed.

…t()/mcpReq.send schema overloads for custom methods
…ation as 2nd arg; export StandardSchemaV1; fix example headers
…ce during async result validation); add core to changeset; setNotificationHandler JSDoc notes 2nd arg
@felixweinberger felixweinberger force-pushed the fweinberger/custom-methods-minimal branch from ab1115e to dc09b1d Compare April 29, 2026 12:37
@felixweinberger

Copy link
Copy Markdown
Contributor Author

@claude review

Comment thread packages/core/src/shared/protocol.ts Outdated
Comment thread examples/client/src/customMethodExample.ts Outdated
@felixweinberger felixweinberger merged commit db83829 into main Apr 29, 2026
15 checks passed
@felixweinberger felixweinberger deleted the fweinberger/custom-methods-minimal branch April 29, 2026 15:38
felixweinberger added a commit that referenced this pull request Apr 29, 2026
felixweinberger added a commit that referenced this pull request Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2-bc v2 backwards-compatibility series

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants